/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.admin.client.subcomponents;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.elf.gwt.admin.client.AdminComponentController;
import com.elf.gwt.admin.client.components.CategoriesProductsComponent;
import com.elf.gwt.admin.client.utils.AdminUtils;
import com.elf.gwt.common.client.access.JSONServerAccess;
import com.elf.gwt.common.client.callback.SubComponentCallback;
import com.elf.gwt.common.client.components.CommonSimpleComponent;
import com.elf.gwt.common.client.model.CategoryModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;

/**
 *  
 */
public class CategorySubComponent extends AdminSubComponent
{
	protected CategoriesProductsComponent component;
	protected CategoryModel categoryModel;
	protected Grid grid;

	protected HorizontalPanel buttonPanel = null;
	protected Button editButton;
	protected Button moveButton;
	protected Button deleteButton;
	protected Button cancelButton;
	protected Button saveButton;
	protected FormPanel form;

	protected boolean edit = false;

	/**
	 * Constructor
	 */
	public CategorySubComponent(CommonSimpleComponent component, CategoryModel categoryModel, AdminComponentController controller, String handle, SubComponentCallback callback)
	{
		super(controller, handle, null, callback);
		this.component = (CategoriesProductsComponent)component;
		this.categoryModel = categoryModel;
	}

	public void build()
	{
		TextBox textBox1 = null;
		Image image = new Image();
		String imageUrl = AdminUtils.getImageProductsDirectory() + categoryModel.getImage();
		image.setUrl(imageUrl);
		image.setTitle(categoryModel.getName());
		String[] imageSize = categoryModel.getImageSize();
		image.setSize(imageSize[0], imageSize[1]);

		if (edit)
		{
			grid = new Grid(12, 1);
			grid.setText(0, 0, "Category Name:");
			textBox1 = new TextBox();
			textBox1.setName("categoryName");
			textBox1.setText(categoryModel.getName());
			grid.setWidget(1, 0, textBox1);

			component.setFocusWidget(textBox1);

			grid.setWidget(3, 0, image);
			grid.setText(4, 0, categoryModel.getImage());
			grid.setText(6, 0, "Category Image:");
			FileUpload upload = new FileUpload();
			upload.setName("categoryImage");
			grid.setWidget(7, 0, upload);
			grid.setText(9, 0, "Sort Order:");
			TextBox textBox2 = new TextBox();
			textBox2.setText(String.valueOf(categoryModel.getSortOrder()));
			textBox2.setName("sortOrder");
			grid.setWidget(10, 0, textBox2);
			grid.setText(11, 0, categoryModel.getMessage());
		}
		else
		{
			grid = new Grid(10, 1);

			DateTimeFormat df = CommonUtils.dateTimeFormat;
			Date dateAdded = categoryModel.getDateAdded();
			Date lastModified = categoryModel.getLastModified();

			grid.setText(0, 0, categoryModel.getName());
			if (dateAdded != null) grid.setText(2, 0, "Date Added: " + df.format(dateAdded));
			if (lastModified != null) grid.setText(3, 0, "Last Modified: " + df.format(lastModified));


			grid.setWidget(5, 0, image);
			grid.setText(6, 0, categoryModel.getImage());
			grid.setHTML(8, 0, "Subcategories: " + categoryModel.getChildList().size() + "<br/>Products: " + categoryModel.getCount());
			grid.setText(9, 0, categoryModel.getMessage());
		}

		clear();
		add(new InlineHTML("<br/><br/><br/>"));

		if (buttonPanel == null) 
		{
			buttonPanel = new HorizontalPanel();
			buttonPanel.setStyleName("ZButtons");

			editButton = new Button("edit", editHandler);
			editButton.addStyleName("ComponentLink");
			buttonPanel.add(editButton);
			buttonPanel.add(new InlineHTML("&nbsp;&nbsp;"));

			deleteButton = new Button("delete", deleteHandler);
			deleteButton.addStyleName("ComponentLink");
			buttonPanel.add(deleteButton);
			buttonPanel.add(new InlineHTML("&nbsp;&nbsp;"));

			moveButton = new Button("move", moveHandler);
			moveButton.addStyleName("ComponentLink");
			buttonPanel.add(moveButton);
			buttonPanel.add(new InlineHTML("&nbsp;&nbsp;"));

			cancelButton = new Button("cancel", cancelHandler);
			cancelButton.addStyleName("ComponentLink");
			buttonPanel.add(cancelButton);
			buttonPanel.add(new InlineHTML("&nbsp;&nbsp;"));

			saveButton = new Button("save", saveHandler);
			saveButton.addStyleName("ComponentLink");
			buttonPanel.add(saveButton);
		}

		editButton.setVisible(!edit);
		deleteButton.setVisible(!edit && categoryModel.getChildList().size() == 0 && categoryModel.getCount() == 0);
		moveButton.setVisible(!edit);
		cancelButton.setVisible(edit);
		saveButton.setVisible(edit);

		add(buttonPanel);

		if (edit)
		{
			form = new FormPanel();
			form.setAction(GWT.getHostPageBaseURL() + JSONServerAccess.DEFAULT_REQUEST_URL);
			form.setEncoding(FormPanel.ENCODING_MULTIPART);
			form.setMethod(FormPanel.METHOD_POST);
			FlowPanel formInputs = new FlowPanel();
			formInputs.add(grid);
			formInputs.add(new Hidden("handle", getHandle()));
			formInputs.add(new Hidden("action", "SaveCategory"));
			formInputs.add(new Hidden("categoryId", String.valueOf(categoryModel.getId())));
			formInputs.add(new Hidden("parentCategoryId", String.valueOf(categoryModel.getParentId())));
			form.setWidget(formInputs);

			form.addSubmitCompleteHandler(new SubmitCompleteHandler(){
				public void onSubmitComplete(SubmitCompleteEvent event) {
					String responseText = event.getResults();
					responseText = responseText.replace('\n', ' ');
					JSONValue jsonValue = JSONParser.parseLenient(responseText);
					JSONValue componentValue = CommonUtils.getComponentValue(jsonValue, getHandle());
					if (componentValue != null)
					{
						JSONArray jsonArray;
						if ((jsonArray = componentValue.isArray()) != null)
						{
							int sz = jsonArray.size();		
							for (int i = 0; i < sz; i++)
							{
								jsonValue = jsonArray.get(i);
								JSONObject jsonObject;
								if ((jsonObject = jsonValue.isObject()) != null)
								{
									int count = categoryModel.getCount();
									categoryModel.update(jsonObject);
									categoryModel.setCount(count);
									if (categoryModel.getErrorCode() < -1) {
										edit = true;
										build();
									}
									else {
										superAction = null;
										callback.onSuccess(thisComponent);
									}

								}
							}
						}
					}
				}
			}); 

			add(form);
			if (form.isVisible())
			{
				textBox1.setFocus(true);
			}
		}
		else
		{
			add(grid);
		}

		categoryModel.setErrorCode(0);
		categoryModel.setMessage("");
	}

	protected ClickHandler editHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			edit = true;
			build();
		}
	};

	protected ClickHandler cancelHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			if (categoryModel.getId() == 0) {
				callback.onSuccess(thisComponent);
			}
			else {
				edit = false;
				build();
			}
		}
	};

	protected ClickHandler moveHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			DialogBox dialogBox = createMoveDialogBox();
			dialogBox.center();
			dialogBox.show();

		}
	};

	protected ClickHandler saveHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			form.submit();
		}
	};

	protected ClickHandler deleteHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			if (Window.confirm("Delete Category?")) {
				superAction = "DeleteCategory";
				callback.onSuccess(thisComponent);
			}
		}
	};

	public boolean isEdit() {
		return edit;
	}

	public void setEdit(boolean edit) {
		this.edit = edit;
	}

	protected DialogBox createMoveDialogBox() {
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setStyleName(component.getHandle()+ "DialogBox");
		dialogBox.addStyleName("DialogBox");
		dialogBox.setText("Select New Parent Category");
		FlowPanel dialogContents = new FlowPanel();
		dialogBox.setWidget(dialogContents);
		ListBox categoryListBox = new ListBox();
		categoryListBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				ListBox listBox = (ListBox)event.getSource();
				int index = listBox.getSelectedIndex();
				String value = listBox.getValue(index);
				if (value != null)
				{
					component.setSelectedCategoryId(Integer.parseInt(value));
					superAction = "MoveCategory";
					dialogBox.hide();
					callback.onSuccess(thisComponent);
				}
			}
		});

		dialogContents.add(categoryListBox);
		Button closeButton = new Button("close",
				new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});
		dialogContents.add(closeButton);

		categoryListBox.addItem("--Please Select--","-1");
		buildCategoryListBox(categoryListBox, component.getCategoryModel(0), "");
		return dialogBox;
	}

	public static void buildCategoryListBox(ListBox listBox, CategoryModel cmodel, String prefix)
	{		
		if (!(cmodel.getCount() > 0 && cmodel.getChildList().size() == 0)) {
			listBox.addItem(prefix + cmodel.getName(),String.valueOf(cmodel.getId()));
		}
		List<CategoryModel> children = cmodel.getChildList();
		Iterator<CategoryModel> iter = children.iterator();
		while(iter.hasNext())
		{
			CategoryModel child = iter.next();
			buildCategoryListBox(listBox, child, prefix + "+");
		}
	}
}
